/*!
 * @file
 * @brief auto support portmap in routers by upnp protocal
 * @date  2013-8-13
 * @author suijz
 *
 * support any port to map ruters,and back real extern port
 */


#ifndef _UPNP_

typedef unsigned short Port;

typedef struct 
{
    Port eport;///< extern port
    Port iport;///< inner port
    const char*    eaddr;///< extern ip address
    const char*    iaddr;///< inner ip address
    const char*    proto;///< tcp or udp
}PortMapInfo;

 
class UPnP
{
enum 
{
   TCP,
   UDP,
};
public:
    static UPnP& instance();
    /*!
    @brief map local port to router
    @param[in] iport  will map by localip&port&proto
    @param[in] desc  detail for port map info
    @param[in] proto tcp or udp,0-tcp;1-udp
    @param[out] eport mapped port
    @return 0 ok;!=0 err, 0: mapped port,that's router's extern port for local ip&port&proto

    map localport to router's extern port,default map extern port to same port
    but if that's extern port take up by other ip&port,will auto select from[1000,1250]
    */
    int regMapPort(Port iport,Port& rport,const char* desc,int proto=0);
    /*!
    @brief unregister extern port&proto from router
    @param[in] port ,that's return by regMapPort
    @param[in] proto,equal proto of regMapPort function
    @return 0 ok,!=0 err
    */
    int unregMapPort(Port eport,int proto=0);
    void unregAllPort();
    
public:
    int search(int delay=1000);//ms
    int addPort(Port&rport,Port eport, Port iport,
	const char* iaddr=0,const char* desc="need",int proto=0,int duration=0);  
    int addPort(const char* eport,const char* iport,const char* iaddr=0,
		const char* desc="need",const char* proto="TCP",const char* duration="0");  
    int delPort(Port eport,int proto=0);
    int delPort(const char* eport,const char* proto="TCP");
    int findPort(int eport,int proto,char* iaddr,Port& iport);
    int findPort(const char* eport,const char* proto,char* iaddr,char* iport);
private:
    UPnP();
    ~UPnP();
};

#endif
